10 定时器输入实验
定时器正交编码实验 定时器输入捕获实验
up的视频讲解: https://space.bilibili.com/1455872040
up视频里的正交编码实验代码: 👣OLED实验代码
up视频里的输入捕获实验代码: 👣OLED实验代码
1 🔃定时器正交编码实验
1.1 实验连接

1.2 实验原理

- 我们看到旋转编码器的原理图 右边是它的数据手册中给出的具体结构
- 可以看到旋转编码器的
AB两路默认上拉为高电平 - 当我们旋动它的时候 旋转编码器里面的两个开关就交替导通 从而产生
AB两路信号

我们来简单分析一下它的状态序列
当顺时钟旋转的时候
- 在旋转之前
AB两个端子都为高电平1 - 首先
A端子先到低电平0 - 其次 是
B端子到0 - 接着是
A端子上拉到1 - 最后 是
B端子到1
同理 逆时针旋转
- 首先是11
- 然后是10
- 00 01
- 最后是11

通过定时器内部的Encoder Interface正交编码模块 它具体有三种模式
- TI12 也就是对AB两路信号都触发计数 一个完整的通断周期会产生 四个计数脉冲 也叫四分频模式
- TI1 就只对一路信号触发计数 另一路只用来判定方向,一个完整的通断周期产生产生 两个计数脉冲
- TI2 与TI1相同
1.3 CubeMX配置


1.4 实验代码
全局
main()
HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
uint16_t counter = 0;
while(1)里面
counter =__HAL_TIM_GET_COUNTER(&htim1);
if(counter == 2)
{
//LED1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,1);//黄灯亮
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter ==4)
{
//LED2
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,1);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter == 6)
{
//LED3
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,0);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter == 8)
{
//LED4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,0);//绿灯灭
}
else{
//LED关闭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
2 🔃定时器输入捕获实验
2.1 实验连接

2.2 实验原理

如果我们配置为下降沿触发的模式
-
当A端子一个下降沿来的时候 边缘检测电路就会输出一个触发脉冲
-
如果我们不进行分频 那么此时就会将CNT的值锁存到
CCR -
并触发定时器输入捕获中断 我们就可以在中断里面读取
CCR的值 从而得到当前的计数值 -
当第二个下降沿来的时候就会触发第二个脉冲信号
-
此时
CCR又会锁存当前 CNT的计数值 -
然后触发中断 此时再到中断里面读取
CCR的值
我们将两个计数值 相减就可以得到两次边缘所间隔的CNT个数 然后再乘计数脉冲的周期就可以得到间隔的时间

这个计数脉冲的周期具体是这样得到
- 计数脉冲是
PSC预分频器对 RCC的时钟进行 PSC+1分频得到的 - 所以说 计数脉冲的频率 就等于 RCC的时钟频率除以PSC加1
- 同理 计数脉冲的周期 就是频率的倒数
通过这样的方法我们就可以的到两次边沿所间隔的时间
2.3 CubeMX配置



2.4 实验代码
全局
uint8_t flag = 0;
uint32_t cnt1 = 0;
uint32_t cnt2 = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1)
{
if(flag == 0)
{
//cnt1
cnt1 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);
flag++;
}
else if(flag == 1)
{
//cnt2
cnt2 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);
flag++;
}
}
}
main()
HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);
float time = 0;
while(1)里面
if(flag == 2)
{
//cnt2-cnt1 * T
if(cnt2-cnt1<0)
{
cnt2 += 65536;
}
time = (cnt2-cnt1)*0.0001;
printf("cnt1 = %d cnt2 = %d time = %f \r\n",cnt1,cnt2,time);
flag = 0;
}
✅捕获回绕与测量范围
以上保留视频原代码。无符号计数差与回绕处理的工程化说明放在调试补充,不在视频代码中替换实现。
若计数时钟10 kHz,测量上限约6.5536秒。更慢信号要累计溢出次数或降低计数频率;缺少输入时还要设超时,不能一直沿用上一次的测量值。两次同极性边沿间隔为周期,异极性边沿间隔是脉宽。
正交编码器实验先慢转再快转,观察方向和每格计数。机械编码器存在抖动,滤波和解码倍频都会影响每格变化量;反向跳变不应一律解释为程序错误。